#pragma once

/*
    支持读取配置格式：
    user1 caicai
    user2=caicai
    user3 = caicai
    user4 ='cai cai'  111
    user5=  "cai cai 5"  注意，(') 跟 (") 开头，其本身不识别到value，且只识别到配对的引号范围内容 
    user6 ='cai cai  222
    keyonly
    # this will not be recognised
    ; this will not be recognised
*/
#ifdef __cplusplus
extern "C" {
#endif

#define __NOTE_SIGN__ "__NOTE_SIGN__"       // 当key值为这个时，表示当前行是注释
#define __SPACE_LINE_SIGN__ "__SPACE_LINE_SIGN__"       // 当key值为这个时，表示当前行是换行
#define __TOPIC_SIGN__ "__TOPIC_SIGN__"     // 当key值为这个时，表示接下来参数是该topic的参数，一直到换行

#define CONFIG_KEY_LEN      128     // key值最大长度
#define CONFIG_VALUE_LEN    128     // value值最大长度
struct config_list
{
    char key[CONFIG_KEY_LEN];
    char value[CONFIG_VALUE_LEN];
    struct config_list* next;
};

#if __STDC_VERSION__ < 201112
#warning make sure CONFIG_KEY_LEN is larger than __SPACE_LINE_SIGN__, __NOTE_SIGN__, __TOPIC_SIGN__
#else
_Static_assert(CONFIG_KEY_LEN > sizeof(__SPACE_LINE_SIGN__), "CONFIG_KEY_LEN must larger than __SPACE_LINE_SIGN__");
_Static_assert(CONFIG_KEY_LEN > sizeof(__NOTE_SIGN__), "CONFIG_KEY_LEN must larger than __NOTE_SIGN__");
_Static_assert(CONFIG_KEY_LEN > sizeof(__TOPIC_SIGN__), "CONFIG_KEY_LEN must larger than __TOPIC_SIGN__");
#endif

// 初始化
void config_parse_init(struct config_list *list);
// 解析config文件，读取到的配置以链表形式存储
int config_parse_file(struct config_list *list, char *file_name);
// 解析buffer(需以 \0 结尾)，读取到的配置以链表形式存储
int config_parse_buffer(struct config_list *list, char *buffer);
// 解析完成后，通过此函数获取特定key的value值
char* config_parse_get_value_by_key(struct config_list *list, char *key, char *topic);
// 解析完成后，读取某行数据(1开始)。失败返回null
struct config_list *config_parse_get_line(struct config_list *list, int line);
// 获取第n个topic(1开始)。返回指向topic的头
struct config_list *config_parse_get_topic(struct config_list *list, int num);
// 获取第topic的第n个参数(1开始)。
struct config_list *config_parse_get_topic_line(struct config_list *list, char *topic, int line);
// 释放空间
void config_parse_free(struct config_list *list);

// 在配置中添加空行
int config_parse_add_empty(struct config_list *list);
// 在配置中添加一行注释
int config_parse_add_note(struct config_list *list, char *note);
// 在配置中添加一行标题
int config_parse_add_topic(struct config_list *list, char *topic);
// 在配置中添加一行配置
int config_parse_add_line(struct config_list *list, char *key, char *value);
// 把配置添加在后端
int config_parse_add_list(struct config_list *dest, struct config_list *list);
// 生成配置文件，并以文件形式存储
int config_parse_create_file(struct config_list *list, char *file_name);
// 生成配置文件，并以缓存形式存储。buffer空间需要（struct config_list大小）*行数
int config_parse_create_buffer(struct config_list *list, char *buffer, int buffer_len);

#ifdef __cplusplus
}
#endif // __cplusplus
